// copyright 1993 Michael B. Johnson; some portions copyright 1994, MIT
// see COPYRIGHT for reuse legalities
//

#import "RIBTransform.h"

@implementation RIBTransform

+ initialize { return [RIBTransform setVersion:1], self; }

- init
{
  [super init];
  N3D_CopyMatrix(N3DIdentityMatrix, aMatrix);

  return self;
}

- setMatrix:(RtMatrix)newMatrix
{
  N3D_CopyMatrix(newMatrix, aMatrix);
  return self;
}

- getMatrix:(RtMatrix *)matrixPtr
{
  N3D_CopyMatrix(aMatrix, *matrixPtr);
  return self;
}

- (BOOL)theSameAs:otherRIBCommand
{
  RtMatrix  otherMatrix;


  [otherRIBCommand getMatrix:&otherMatrix];

  if (aMatrix[0][0] != otherMatrix[0][0])
  {  return NO;
  }
  if (aMatrix[0][1] != otherMatrix[0][1])
  {  return NO;
  }
  if (aMatrix[0][2] != otherMatrix[0][2])
  {  return NO;
  }
  if (aMatrix[0][3] != otherMatrix[0][3])
  {  return NO;
  }

  if (aMatrix[1][0] != otherMatrix[1][0])
  {  return NO;
  }
  if (aMatrix[1][1] != otherMatrix[1][1])
  {  return NO;
  }
  if (aMatrix[1][2] != otherMatrix[1][2])
  {  return NO;
  }
  if (aMatrix[1][3] != otherMatrix[1][3])
  {  return NO;
  }

  if (aMatrix[2][0] != otherMatrix[2][0])
  {  return NO;
  }
  if (aMatrix[2][1] != otherMatrix[2][1])
  {  return NO;
  }
  if (aMatrix[2][2] != otherMatrix[2][2])
  {  return NO;
  }
  if (aMatrix[2][3] != otherMatrix[2][3])
  {  return NO;
  }

  if (aMatrix[3][0] != otherMatrix[3][0])
  {  return NO;
  }
  if (aMatrix[3][1] != otherMatrix[3][1])
  {  return NO;
  }
  if (aMatrix[3][2] != otherMatrix[3][2])
  {  return NO;
  }
  if (aMatrix[3][3] != otherMatrix[3][3])
  {  return NO;
  }

  return [super theSameAs:otherRIBCommand];
}

- renderSelf:(WW3DCamera *)camera startingAt:(RtFloat)shutterOpenTime endingAt:(RtFloat)shutterCloseTime
{
  RiTransform(aMatrix);

  return self;
}

- transformCTM:(WW3DAttributeState *)attributeState startingAt:(RtFloat)shutterOpenTime endingAt:(RtFloat)shutterCloseTime
{ 
  [attributeState setTransformMatrix:aMatrix];
  return self; 
}

- (BOOL)isMotionBlurrable { return YES; }

- (unsigned long int)maxSampleBandwidth {  return ([super maxSampleBandwidth] + (unsigned long int)(16 * sizeof(RtFloat))); }

- writeEve:(NXStream *)stream atTabLevel:(int)tab
{
   int  i;


   for (i = 0; i < tab; i++)
   {  NXPrintf(stream, "\t");
   }
   NXPrintf(stream, "Transform {");
   NXPrintf(stream, "%f %f %f %f ",  aMatrix[0][0], aMatrix[0][1], aMatrix[0][2], aMatrix[0][3]);
   NXPrintf(stream, "%f %f %f %f ",  aMatrix[1][0], aMatrix[1][1], aMatrix[1][2], aMatrix[1][3]);
   NXPrintf(stream, "%f %f %f %f ",  aMatrix[2][0], aMatrix[2][1], aMatrix[2][2], aMatrix[2][3]);
   NXPrintf(stream, "%f %f %f %f};", aMatrix[3][0], aMatrix[3][1], aMatrix[3][2], aMatrix[3][3]);
   NXPrintf(stream, "; ");

   return self;
}


- writeInventorAtTime:(float)currentTime to:(NXStream *)stream atTabLevel:(int)tab
{
   int  i;


   for (i = 0; i < tab; i++)
   {  NXPrintf(stream, "\t");
   }
   NXPrintf(stream, "ResetTransform {\n");
   for (i = 0; i < (tab+1); i++)
   {  NXPrintf(stream, "\t");
   }
   NXPrintf(stream, "whatToTransform TRANSFORM\n");
   for (i = 0; i < tab; i++)
   {  NXPrintf(stream, "\t");
   }
   NXPrintf(stream, "}\n");
   for (i = 0; i < tab; i++)
   {  NXPrintf(stream, "\t");
   }
   NXPrintf(stream, "MatrixTransform {\n");
   for (i = 0; i < (tab+1); i++)
   {  NXPrintf(stream, "\t");
   }
   NXPrintf(stream, "matrix %f %f %f %f\n", aMatrix[0][0], aMatrix[0][1], aMatrix[0][2], aMatrix[0][3]);
   for (i = 0; i < (tab+1); i++)
   {  NXPrintf(stream, "\t");
   }
   NXPrintf(stream, "       %f %f %f %f\n",  aMatrix[1][0], aMatrix[1][1], aMatrix[1][2], aMatrix[1][3]);
   for (i = 0; i < (tab+1); i++)
   {  NXPrintf(stream, "\t");
   }
   NXPrintf(stream, "       %f %f %f %f\n",  aMatrix[2][0], aMatrix[2][1], aMatrix[2][2], aMatrix[2][3]);
   for (i = 0; i < (tab+1); i++)
   {  NXPrintf(stream, "\t");
   }
   NXPrintf(stream, "       %f %f %f %f\n", aMatrix[3][0], aMatrix[3][1], aMatrix[3][2], aMatrix[3][3]);
   for (i = 0; i < tab; i++)
   {  NXPrintf(stream, "\t");
   }
   NXPrintf(stream, "}");

   return self;

}


- read:(NXTypedStream*)stream 
{
    int version;
    [super read:stream];

    version = NXTypedStreamClassVersion(stream,"RIBTransform");
    if (version == 0) NXReadTypes(stream,"i",&version), version=1;
    if (version == 1)
    {  NXReadArray(stream, "f", 4, aMatrix[0]);
       NXReadArray(stream, "f", 4, aMatrix[1]);
       NXReadArray(stream, "f", 4, aMatrix[2]);
       NXReadArray(stream, "f", 4, aMatrix[3]);
    } 
    else 
    {
    }
    return self;
}

- write:(NXTypedStream*)stream 
{
    [super write:stream];

    NXWriteArray(stream, "f", 4, aMatrix[0]);
    NXWriteArray(stream, "f", 4, aMatrix[1]);
    NXWriteArray(stream, "f", 4, aMatrix[2]);
    NXWriteArray(stream, "f", 4, aMatrix[3]);

    return self;
}


@end
